package com.hockeo.server.rpc.command;

import java.util.HashMap;

import com.hockeo.server.rpc.command.user.executors.GetSessionInfoExecutor;
import com.hockeo.shared.rpc.command.ICommand;
import com.hockeo.shared.rpc.command.IResponse;

/**
 * Utility class that is used to look up command executors.
 *
 * @version $Id$
 * @author jjanke
 */
public class CommandExecutorLookup
{
  private static CommandExecutorLookup                                        d_instance;
  private final HashMap<Class<? extends ICommand<?>>, ICommandExecutor<?, ?>> d_mapExecutors;

  /**
   * Private constructor to avoid external instantiation.
   */
  private CommandExecutorLookup()
  {
    d_mapExecutors = new HashMap<Class<? extends ICommand<?>>, ICommandExecutor<?,?>>();

    // All known command handlers are added below
    //
    register( new GetSessionInfoExecutor() );
  }

  /**
   * Returns an instance of CommandExecutorLookup.
   */
  public static CommandExecutorLookup get()
  {
    if ( d_instance == null )
      d_instance = new CommandExecutorLookup();

    return d_instance;
  }

  /**
   * Registers the given executor.
   *
   * @param cmdExecutor the command executor to be registered
   */
  public final void register( ICommandExecutor<?,?> cmdExecutor )
  {
    d_mapExecutors.put( cmdExecutor.getCommandType(), cmdExecutor );
  }

  /**
   * Returns the executor for the specified command class.
   *
   * @param <S> type of the command to be handled by the executor
   * @param <T> type of the response produced by the executor
   * @param cls the class representing the command to be handled
   * @return the matching handler
   */
  @SuppressWarnings( "unchecked" )
  public <S extends ICommand<T>, T extends IResponse> ICommandExecutor<S, T> getExecutor( Class<S> cls )
  {
    return (ICommandExecutor<S, T>) d_mapExecutors.get( cls );
  }
}
